package com.zyf.project.binaryproto.specification.impl;

import com.zyf.project.binaryproto.specification.EnumSpecification;
import com.zyf.project.binaryproto.type.PrimitiveType;

import java.util.LinkedHashSet;
import java.util.Set;

/**
 * <h1>{@link EnumSpecification} 的实现类</h1>
 *
 * @author Zhou Yifan
 */
public class EnumSpecificationInfo implements EnumSpecification {

    private final PrimitiveType valueType;

    private final Class<?> dataType;

    private final int code;
    private final long version;
    private final String name;
    private final String description;

    private Set<EnumConstant> items = new LinkedHashSet<>();

    public EnumSpecificationInfo(PrimitiveType valueType, int code, long version, String name, String description, Class<?> dataType) {
        this.valueType = valueType;
        this.code = code;
        this.version = version;
        this.name = name;
        this.description = description;
        this.dataType = dataType;
    }

    /**
     * 数据契约的类型编码
     *
     * @return int 值
     */
    @Override
    public int getCode() {
        return code;
    }

    /**
     * 名字
     *
     * @return 字符串
     */
    @Override
    public String getName() {
        return name;
    }

    /**
     * 描述
     *
     * @return 字符串
     */
    @Override
    public String getDescription() {
        return description;
    }

    /**
     * <p>数据契约的版本</p>
     *
     * @return long 值
     */
    @Override
    public long getVersion() {
        return version;
    }

    /**
     * 获取枚举类数据契约类型
     *
     * @return {@link PrimitiveType}
     */
    @Override
    public PrimitiveType getValueType() {
        return valueType;
    }

    /**
     * 获取枚举类各项的值
     *
     * @return int[]
     */
    @Override
    public int[] getItemValues() {
        int[] values = new int[items.size()];
        int i = 0;
        for (EnumConstant it : items) {
            values[i] = it.code;
            i++;
        }
        return values;
    }

    /**
     * 获取枚举类各项的名字
     *
     * @return String[]
     */
    @Override
    public String[] getItemNames() {
        String[] names = new String[items.size()];
        int i = 0;
        for (EnumConstant it : items) {
            names[i] = it.name;
            i++;
        }
        return names;
    }

    public Class<?> getDataType() {
        return dataType;
    }

    public Object[] getConstants() {
        Object[] constants = new Object[items.size()];
        int i = 0;
        for (EnumConstant it : items) {
            constants[i] = it.constant;
            i++;
        }
        return constants;
    }

    public void addConstant(EnumConstant item) {
        items.add(item);
    }

    public void setItems(Set<EnumConstant> items) {
        this.items = items;
    }

    /**
     * <h1>枚举类常量</h1>
     *
     * @author Zhou Yifan
     */
    public static class EnumConstant {

        private final int code;

        private final String name;

        private final Object constant;

        public int getCode() {
            return code;
        }

        public String getName() {
            return name;
        }

        public Object getConstant() {
            return constant;
        }

        public EnumConstant(int code, String name, Object constant) {
            this.code = code;
            this.name = name;
            this.constant = constant;
        }
    }
}
